<template>
  <div class="mala-swiper" :style="styleObj" @mouseenter="handleMouseEnter" @mouseleave="handleMouseLeave">
    <div class="mala-swiper-list" :style="styleObj" ref="listRef">
      <template v-for="item in imgListData" :key="item">
        <img :src="item" alt="" :style="styleObj" />
      </template>
    </div>
    <div class="mala-swiper-indicators" v-if="indicator">
      <span
        v-for="(item, index) in imgList"
        :class="['mala-swiper-indicator', index === currentIndex - 1 ? 'mala-swiper-indicator-active': '']"
        :key="item"
        :style="{backgroundColor: index === currentIndex - 1 ? indicatorActiveColor : indicatorColor}">
      </span>
    </div>
    <div class="mala-swiper-left" v-if="arrow" @click="handleLastClick" :style="arrowStyleObj" v-show="arrowShow">
      <img :src="leftArrow || leftArrowDefault" alt="左箭头">
    </div>
    <div class="mala-swiper-right" v-if="arrow" @click="handleNextClick" :style="arrowStyleObj" v-show="arrowShow">
      <img :src="rightArrow || rightArrowDefault" alt="右箭头">
    </div>
  </div>
</template>

<script>
export default {
  name: "mala-swiper"
}
</script>

<script setup>
import { computed, ref, onMounted, onBeforeUnmount } from "vue"
import leftArrowDefault from "./assets/zuojiantou_huaban.png"
import rightArrowDefault from "./assets/youjiantou_huaban.png"

const props = defineProps({
  imgList: {
    type: Array,
    required: true
  },
  width: {
    type: Number
  },
  height: {
    type: Number
  },
  delay: {
    type: Number,
    default: 3000
  },
  speed: {
    type: String,
    default: "default",
    validator(value) {
      return ["default", "faster", "slower"].includes(value)
    }
  },
  indicator: {
    type: Boolean,
    default: true
  },
  arrow: {
    type: Boolean,
    default: true
  },
  hover: {
    type: Boolean,
    default: true
  },
  leftArrow: {
    type: String
  },
  rightArrow: {
    type: String
  },
  indicatorColor: {
    type: String
  },
  indicatorActiveColor: {
    type: String
  }
})
// 图片数据加工
const imgListData = computed(() => {
  return [props.imgList[props.imgList.length - 1], ...props.imgList, props.imgList[0]]
})
// 容器宽度 + 高度样式
const styleObj = computed(() => {
  let width = props.width ? props.width + "px" : ""
  let height = props.height ? props.height + "px" : ""
  return { width, height }
})

// 左右箭头宽度+高度样式
const arrowStyleObj = computed(() => {
  let width = props.width ? props.width / 10 + "px" : ""
  let height = props.width ? props.width / 10 + "px" : ""
  return { width, height }
})
// --------------图片轮播逻辑--------------------
// speed配置
const speedObj = {
  default: 800,
  faster: 400,
  slower: 1600
}
// 图片列表dom元素
const listRef = ref()
// 获取容器宽度
const containerWidth = props.width || 400
// 当前轮播图片的下标
const currentIndex = ref(1)

// 每16毫秒滚动的距离
const distance = containerWidth / speedObj[props.speed] * 16
// 图片滑动函数
function swiperMove(direction = "right") {
  return new Promise(resolve => {
    const timer = setInterval(() => {
      if (direction === "right") {
        if (parseInt(listRef.value.style.left) - distance <= -currentIndex.value * containerWidth) {
          clearInterval(timer)
          listRef.value.style.left = -currentIndex.value * containerWidth + "px"
          resolve()
        } else {
          listRef.value.style.left = parseInt(listRef.value.style.left) - distance + "px"
        }
      } else {
        if (parseInt(listRef.value.style.left) + distance >= -currentIndex.value * containerWidth) {
          clearInterval(timer)
          listRef.value.style.left = -currentIndex.value * containerWidth + "px"
          resolve()
        } else {
          listRef.value.style.left = parseInt(listRef.value.style.left) + distance + "px"
        }
      }
    }, 16)
  })
}
// 能否滚动标志
let flag = true
// 上一张
const handleLastClick = async () => {
  if (!flag) return
  flag = false
  currentIndex.value--
  await swiperMove("left")
  flag = true
  if (currentIndex.value === 0) {
    //   setTimeout(() => {
    currentIndex.value = imgListData.value.length - 2
    listRef.value.style.left = -currentIndex.value * containerWidth + "px"
    //   }, 2 * containerWidth)
  }
}
// 下一张
const handleNextClick = async () => {
  if (!flag) return
  flag = false
  currentIndex.value++
  await swiperMove()
  flag = true
  if (currentIndex.value === imgListData.value.length - 1) {
    // setTimeout(() => {
    currentIndex.value = 1
    listRef.value.style.left = -currentIndex.value * containerWidth + "px"
    // }, 2 * containerWidth)
  }
}

// 定时器
let timer = null
// 控制左右箭头的显示与隐藏
const arrowShow = ref(false)

// 鼠标进入事件
const handleMouseEnter = () => {
  arrowShow.value = true
  if (props.hover) {
    clearInterval(timer)
  }
}

// 鼠标离开事件
const handleMouseLeave = () => {
  arrowShow.value = false
  if (props.hover) {
    listRef.value.style.left = -containerWidth * currentIndex.value + "px"
    timer = setInterval(() => {
      handleNextClick()
    }, props.delay)
  }
}

// ------------------组件生命周期-------------------------
onMounted(() => {
  listRef.value.style.left = -containerWidth + "px"
  timer = setInterval(() => {
    handleNextClick()
  }, props.delay)
})

onBeforeUnmount(() => {
  clearInterval(timer)
})
</script>